package com.xu.cloud.common.idempotent;

import com.xu.cloud.common.constant.HttpConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 幂等性处理拦截器
 *
 * @author xuguan
 * @since 2025/3/17
 */
@Slf4j
public class IdempotentHandlerInterceptor implements HandlerInterceptor {
    private final IdempotentIfc idempotentIfc;
    private String idempotentToken;
    private boolean checkIdempotent = false;

    public IdempotentHandlerInterceptor(IdempotentIfc idempotentIfc) {
        this.idempotentIfc = idempotentIfc;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("幂等性校验拦截器前置执行开始");
        if (!(handler instanceof HandlerMethod)) {
            log.info("跳过幂等性校验拦截器");
            return true;
        }
        if (!((HandlerMethod) handler).hasMethodAnnotation(Idempotent.class)) {
            log.info("跳过幂等性校验拦截器");
            return true;
        }
        idempotentToken = request.getHeader(HttpConstant.HEADER_IDEMPOTENT_TOKEN);
        checkIdempotent = idempotentIfc.checkIdempotentToken(idempotentToken);
        log.info("幂等性校验拦截器前置执行结束, checkIdempotent={}", checkIdempotent);
        return checkIdempotent;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (checkIdempotent) {
            idempotentIfc.postProcess(idempotentToken);
            log.info("幂等性校验拦截器后置执行结束");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if (checkIdempotent) {
            idempotentIfc.finallyProcess(idempotentToken, ex);
            log.info("幂等性校验拦截器最终执行结束");
        }
    }
}
